package device

import (
	"encoding/json"
	"fmt"
	"iot/common"
	"strings"
	"sync"
	"time"
)

type SRtValue struct {
	ArgIndex string              `gorm:"-" json:"arg"`
	Value    string              `gorm:"-" json:"value"`
	TimeMark time.Time           `gorm:"-" json:"time_mark"`
	Source   common.EDataSource  `gorm:"-" json:"source"`
	Quality  common.EDataQuality `gorm:"-" json:"quality"`
}

func (s SRtValue) String() string {
	// 创建一个便于格式化的临时结构
	type printable struct {
		ArgIndex string              `json:"arg"`
		Value    string              `json:"value"`
		TimeMark string              `json:"time_mark"`
		Source   common.EDataSource  `json:"source"`
		Quality  common.EDataQuality `json:"quality"`
	}

	p := printable{
		ArgIndex: s.ArgIndex,
		Value:    s.Value,
		TimeMark: s.TimeMark.Format("2006-01-02 15:04:05.000"),
		Source:   s.Source,
		Quality:  s.Quality,
	}

	// 使用json.MarshalIndent获取格式化的JSON
	data, err := json.MarshalIndent(p, "", "  ")
	if err != nil {
		// 如果JSON序列化失败，返回fallback格式
		return fmt.Sprintf("SRtValue{ArgIndex:%q, Value:%q, TimeMark:%s, Source:%v, Quality:%v}",
			s.ArgIndex, s.Value, s.TimeMark.Format(time.RFC3339Nano), s.Source, s.Quality)
	}

	return string(data)
}

type CArgument struct {
	//参数信息
	common.SArgumentInfo

	//参数实时数据
	SRtValue
	RtInfoMu sync.RWMutex

	//跟随上报参数
	FollorIdxs []string
}

func (arg *CArgument) Show(isRt bool) string {
	var buf strings.Builder
	if isRt {
		rtval := arg.Rt()
		var qua string
		switch rtval.Quality {
		case common.EDataQualityGood:
			qua = "可信"
		case common.EDataQualityBad:
			qua = "一般"
		case common.EDataQualityNormal:
			qua = "不可信"
		default:
			qua = "不可信"
		}

		var src string
		switch rtval.Source {
		case common.EDataSourceAcquisition:
			src = "采集"
		case common.EDataSourceCalculation:
			src = "计算"
		case common.EDataSourceManual:
			src = "置数"
		default:
			src = "采集"
		}

		buf.WriteString(fmt.Sprintf("%s | %s | %s | %s | %s\n", arg.Name, rtval.Value, src, qua, rtval.TimeMark.Format("2006-01-02 15:04:05")))
	} else {
		buf.WriteString(fmt.Sprintf("=================== %s ===================\n", arg.Name))
		buf.WriteString(fmt.Sprintf("描述: %s\n", arg.Descr))
		var argType string
		switch arg.ArgType {
		case common.EArgTypeDev:
			argType = "设备参数"
		case common.EArgTypeDefault:
			argType = "默认值参数"
		case common.EArgTypeCustum:
			argType = "自定义参数"
		default:
			argType = "未知类型"
		}
		buf.WriteString(fmt.Sprintf("参数类型: %s\n", argType))

		// 值类型描述
		var valueType string
		switch arg.ValueType {
		case common.EArgTypeShort, common.EArgTypeInt:
			valueType = "整数"
		case common.EArgTypeFloat:
			valueType = "浮点数"
		case common.EArgTypeString:
			valueType = "字符串"
		case common.EArgTypeBool:
			valueType = "布尔值"
		case common.EArgTypeBytes:
			valueType = "字节数组"
		default:
			valueType = "未知"
		}
		buf.WriteString(fmt.Sprintf("值类型: %s\n", valueType))

		// 默认值（参数定义中的值）
		if arg.SArgumentInfo.Value != "" {
			buf.WriteString(fmt.Sprintf("默认值: %s\n", arg.SArgumentInfo.Value))
		}

		// 推送类型描述
		var pushType string
		switch arg.PushType {
		case common.EPushNever:
			pushType = "不推送"
		case common.EPushOnChange:
			pushType = "变化时推送"
		case common.EPushOnInterval:
			pushType = "定时推送"
		case common.EPushOnChangeAndTime:
			pushType = "变化+定时推送"
		default:
			pushType = "不推送"
		}
		buf.WriteString(fmt.Sprintf("推送类型: %s\n", pushType))

		// 写权限描述
		var writeEnable string
		if arg.EnWrite == common.EArgWriteEnabled {
			writeEnable = "允许写入"
		} else {
			writeEnable = "禁止写入"
		}
		buf.WriteString(fmt.Sprintf("写权限: %s\n", writeEnable))

		// 推送条件（如果有）
		if arg.PushCondition != "" {
			buf.WriteString(fmt.Sprintf("推送条件: %s\n", arg.PushCondition))
		}

		// 计算脚本（如果有）
		if arg.CalculationPlugin != "" {
			buf.WriteString(fmt.Sprintf("计算脚本: %s\n", arg.CalculationPlugin))
		}

		// 字节序描述
		var byteOrder string
		switch arg.ByteOrder {
		case common.EByteOrderLittleEndian:
			byteOrder = "小端序"
		case common.EByteOrderBigEndian:
			byteOrder = "大端序"
		default:
			byteOrder = "小端序"
		}
		buf.WriteString(fmt.Sprintf("字节序: %s\n", byteOrder))

		// 历史存储状态
		var historyStatus string
		if arg.IsEnableHistory == common.Enable {
			historyStatus = "启用"
		} else {
			historyStatus = "禁用"
		}
		buf.WriteString(fmt.Sprintf("历史存储: %s\n", historyStatus))

		// 跟随上报参数（如果有）
		if len(arg.FollorIdxs) > 0 {
			buf.WriteString("跟随上报参数:\n")
			for _, idx := range arg.FollorIdxs {
				buf.WriteString(fmt.Sprintf("    - %s\n", idx))
			}
		}
	}

	return buf.String()
}

func (arg *CArgument) Rt() SRtValue {
	arg.RtInfoMu.RLock()
	defer arg.RtInfoMu.RUnlock()
	return arg.SRtValue
}

func (arg *CArgument) SetRt(v SRtValue) {
	arg.RtInfoMu.Lock()
	defer arg.RtInfoMu.Unlock()
	arg.SRtValue = v
}
